Data Transfer |
A socket is commonly used to transfer data between two computers. In this section, we will develop a server program and a client program to test data transfer. The following set of two programs illustrates how to interchange a set of files from one computer to another one. In this case, the JPG files will be moved from the server to the client and the GIF files will be moved from the client to the server. The figure below illustrates the objects involved in data transfer. Un socket se usa comúnmente para transferir datos entre dos computadoras. En esta sección, desarrollaremos un programa servidor y un programa cliente para probar la transferencia de datos. El siguiente conjunto de dos programas ilustra cómo intercambiar un conjunto de archivos desde una computadora a otra. En este caso, los archivos JPG se moverán del servidor al cliente y los archivos GIF se moverán del cliente al servidor. La figura de abajo ilustra los objetos involucrados en la transferencia de datos. |
Problem 1 |
Cree a Wintempla dialog application called FileServer. After creating the application, edit the stdafx.h to enable sockets. Cree una aplicación de diálogo de Wintempla llamada FileServer. Después de crear el programa, edite el archivo stdafx.h para habilitar los sockets. |
stdafx.h |
. . . //_________________________________________ Sockets & Cryptography #define WIN_SOCKETS_SUPPORT . . . |
Step A |
Create a folder in your computer called ImgServer and place ten JPG files inside this folder. The example below shows the folder with Mountains pictures. Cree una carpeta en su computadora llamada ImgServer y coloque diez archivos JPG dentro de esta carpeta. El ejemplo de abajo muestra la carpeta con fotos de montañas. |
Step B |
Edit the GUI: add a textbox (multiline, read only, with vertical and horizontal scrollbars) and two buttons as shown. Double click in the GUI editor outside the controls, and in the Event Tab set the events: App (WM_APP) and Timer (WM_TIMER). Edite la GUI: agregue una caja de texto (multiline, read only, with vertical and horizontal scrollbars) y dos botones como se muestra. Haga clic doble en el editor de la GUI afuera de los controles, y en la pestaña de eventos marque los eventos: App (WM_APP) y Timer (WM_TIMER). |
Step C |
Edit the files FileServer.h and FileServer.cpp. Compile your program and verify that it does not have any errors. Edite los archivos FileServer.h y FileServer.cpp. Compile su programa y verifique que este no tiene ningún error. |
FileServer.h |
#pragma once //______________________________________ FileServer.h #include "Resource.h" class FileServer: public Win::Dialog { public: FileServer() { } ~FileServer() { } wstring path; vector<Mt::SocketLink> socketLink; Mt::SocketManager manager; void DisplayStatusInformation(); protected: . . . }; |
FileServer.cpp |
. . . void FileServer::Window_Open(Win::Event& e) { btStop.Enabled = false; //_________________________________________________ 1. Setup the server: port 22 using TCP const size_t socketCount = 10; size_t i; socketLink.resize(socketCount); for (i = 0; i < socketCount; i++) { socketLink[i].port = 22; socketLink[i].protocol = IPPROTO_TCP; manager.socketLink.push_back(&socketLink[i]); } manager.wm_message = WM_APP; // This message will be sent, when the server stops manager.hWnd = hWnd; // The message will be sent to this window } void FileServer::btStart_Click(Win::Event& e) { tbxStatusInfo.SetWindowText(NULL); //_________________________________________________ 1. Prompt the user to select a file Win::FileDlg dlg; dlg.Clear(); dlg.SetFilter(L"JPG files (*.jpg)\0*.jpg\0\0", 0, L"jpg"); if (dlg.BeginDialog(hWnd, L"Open", false) != TRUE) return; path = dlg.GetFilePath(); wstring filter = path; filter += L"\\*.jpg"; vector<_tfinddata_t> filelist; const int count = Sys::FileDirectory::GetFileList(filter.c_str(), filelist); if (count <= 0) return; //_________________________________________________ 2. Number of Listen sockets const int numListenSockets = manager.GetNumberListenSockets(socketLink[0].port , socketLink[0].protocol); //_________________________________________________ 3. For each file wstring filename; Mt::SocketPacket packet; for (int i = 0; i < count; i++) { filename = path; filename += L"\\"; filename += filelist[i].name; //___________________________________________ 3.1. Load the file if (packet.Load(filename.c_str()) == false) { this->MessageBox(filename, L"Error loading", MB_OK | MB_ICONERROR); break; } //___________________________________________ 3.2. Push the file content in the "send queue" of the first available socket link socketLink[numListenSockets].PushInSendQueue(packet); } //_________________________________________________ 4. Run the server in a separated thread this->timer.Set(1, 1000); this->btStart.Enabled = false; this->btStop.Enabled = true; this->EnableCloseButton(false); manager.RunServerX(); } void FileServer::btStop_Click(Win::Event& e) { manager.Stop(); } void FileServer::Window_Timer(Win::Event& e) { DisplayStatusInformation(); } void FileServer::Window_App(Win::Event& e) { //_________________________________________________ 1. All files have been sent this->timer.Kill(1); this->btStart.Enabled = true; this->btStop.Enabled = false; this->EnableCloseButton(true); this->tbxStatusInfo.SetWindowText(NULL); //_________________________________________________ 2. Number of Listen sockets const int numListenSockets = manager.GetNumberListenSockets(socketLink[0].port , socketLink[0].protocol); //_________________________________________________ 3. Save the received data to files Mt::SocketPacket package; int n = 1; wchar_t filename[1024]; while (socketLink[numListenSockets].GetRecvQueueSize() > 0) { if (socketLink[numListenSockets].RecvQueuePop(package) == true) { _snwprintf_s(filename, 1024, _TRUNCATE, L"%s\\%02d.gif", path.c_str(), n++); if (package.Save(filename) == false) { this->MessageBox(L"Unable to save GIF file", L"FileServer", MB_OK | MB_ICONERROR); } } } DisplayStatusInformation(); } void FileServer::DisplayStatusInformation() { vector<wstring> text; manager.statusInfo.Get(text); size_t count = text.size(); size_t i; wstring result; for (i = 0; i < count; i++) { result += text[i]; result += L"\r\n"; } tbxStatusInfo.Text = result; } |
Problem 2 |
Cree a Wintempla dialog application called FileClient. After creating the application, edit the stdafx.h to enable sockets. Cree una aplicación de diálogo de Wintempla llamada FileClient. Después de crear el programa, edite el archivo stdafx.h para habilitar los sockets. |
stdafx.h |
. . . //_________________________________________ Sockets & Cryptography #define WIN_SOCKETS_SUPPORT . . . |
Step A |
Create a folder in your computer called ImgClient and place ten GIF files inside this folder. The example below shows the folder with Cartoons. Cree una carpeta en su computadora llamada ImgClient y coloque diez archivos GIF dentro de esta carpeta. El ejemplo de abajo muestra la carpeta con caricaturas. |
Step B |
Edit the GUI: add a textbox (multiline, read only, with vertical and horizontal scrollbars) and two buttons as shown. Double click in the GUI editor outside the controls, and in the Event Tab set the events: App (WM_APP) and Timer (WM_TIMER). Edite la GUI: agregue una caja de texto (multiline, read only, with vertical and horizontal scrollbars) y dos botones como se muestra. Haga clic doble en el editor de la GUI afuera de los controles, y en la pestaña de eventos marque los eventos: App (WM_APP) y Timer (WM_TIMER). |
Step C |
Edit the files FileClient.h and FileClient.cpp. Compile your program and verify that it does not have any errors. Edite los archivos FileClient.h y FileClient.cpp. Compile su programa y verifique que este no tiene ningún error. |
FileClient.h |
#pragma once //______________________________________ FileClient.h #include "Resource.h" class FileClient: public Win::Dialog { public: FileClient() { } ~FileClient() { } wstring path; Mt::SocketLink socketLink; Mt::SocketManager manager; void DisplayStatusInformation(); protected: . . . }; |
FileClient.cpp |
. . . void FileServer::Window_Open(Win::Event& e) { btStop.Enabled = false; //_________________________________________________ 1. Setup the server: port 22 using TCP const size_t socketCount = 10; size_t i; socketLink.resize(socketCount); for (i = 0; i < socketCount; i++) { socketLink[i].port = 22; socketLink[i].protocol = IPPROTO_TCP; manager.socketLink.push_back(&socketLink[i]); } manager.wm_message = WM_APP; // This message will be sent, when the server stops manager.hWnd = hWnd; // The message will be sent to this window } void FileServer::btStart_Click(Win::Event& e) { tbxStatusInfo.SetWindowText(NULL); //_________________________________________________ 1. Prompt the user to select a file Win::FileDlg dlg; dlg.Clear(); dlg.SetFilter(L"JPG files (*.jpg)\0*.jpg\0\0", 0, L"jpg"); if (dlg.BeginDialog(hWnd, L"Open", false) != TRUE) return; path = dlg.GetFilePath(); wstring filter = path; filter += L"\\*.jpg"; vector<_tfinddata_t> filelist; const int count = Sys::FileDirectory::GetFileList(filter.c_str(), filelist); if (count <= 0) return; //_________________________________________________ 2. Number of Listen sockets const int numListenSockets = manager.GetNumberListenSockets(socketLink[0].port , socketLink[0].protocol); //_________________________________________________ 3. For each file wstring filename; Mt::SocketPacket packet; for (int i = 0; i < count; i++) { filename = path; filename += L"\\"; filename += filelist[i].name; //___________________________________________ 3.1. Load the file if (packet.Load(filename.c_str()) == false) { this->MessageBox(filename, L"Error loading", MB_OK | MB_ICONERROR); break; } //___________________________________________ 3.2. Push the file content in the "send queue" of the first available socket link socketLink[numListenSockets].PushInSendQueue(packet); } //_________________________________________________ 4. Run the server in a separated thread this->timer.Set(1, 1000); this->btStart.Enabled = false; this->btStop.Enabled = true; this->EnableCloseButton(false); manager.RunServerX(); } void FileServer::btStop_Click(Win::Event& e) { manager.Stop(); } void FileServer::Window_Timer(Win::Event& e) { DisplayStatusInformation(); } void FileServer::Window_App(Win::Event& e) { //_________________________________________________ 1. All files have been sent this->timer.Kill(1); this->btStart.Enabled = true; this->btStop.Enabled = false; this->EnableCloseButton(true); this->tbxStatusInfo.SetWindowText(NULL); //_________________________________________________ 2. Number of Listen sockets const int numListenSockets = manager.GetNumberListenSockets(socketLink[0].port , socketLink[0].protocol); //_________________________________________________ 3. Save the received data to files Mt::SocketPacket package; int n = 1; wchar_t filename[1024]; while (socketLink[numListenSockets].GetRecvQueueSize() > 0) { if (socketLink[numListenSockets].RecvQueuePop(package) == true) { _snwprintf_s(filename, 1024, _TRUNCATE, L"%s\\%02d.gif", path.c_str(), n++); if (package.Save(filename) == false) { this->MessageBox(L"Unable to save GIF file", L"FileServer", MB_OK | MB_ICONERROR); } } } DisplayStatusInformation(); } void FileServer::DisplayStatusInformation() { vector<wstring> text; manager.statusInfo.Get(text); size_t count = text.size(); size_t i; wstring result; for (i = 0; i < count; i++) { result += text[i]; result += L"\r\n"; } tbxStatusInfo.Text = result; } |
Step D |
Run the ServerFile program and click the Start button, when the File Dialog opens select a file from the ImgServer folder. Then, run the ClientFile program and click the Start button, when the File Dialog opens select a file from the ImgClient folder. Wait until the client finishes and then stop the server. Finally, verify the folders ImgClient and ImgServer. Ejecuje el programa ServerFile e haga clic en el botón de Start, cuando el diálogo de Archivos se abra seleccione un archivo de la carpeta ImgServer. Entonces, ejecute el programa ClientFile y haga clic en el botón de Start, cuando el diálogo de Archivos se abra seleccione un archivo de la carpeta ImgClient. Espere hasta que el cliente termine y entonces detenga el servidor. Finalmente, verifique las carpetas ImgClient y ImgServer. |